package org.yaukie.websocket.handler;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.yaukie.model.Message;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

/**
 * websocket 消息处理器
 * @author yaukie 
 *
 */
public class WebSocketHander implements WebSocketHandler{

	private static final Logger log = Logger.getLogger(WebSocketHander.class);
	
	  public static final Map<String, WebSocketSession> userSocketSessionMap;
	  
	    static {
	        userSocketSessionMap = new HashMap<String, WebSocketSession>();
	    }
	 
	 private static final ArrayList<WebSocketSession> users = new ArrayList<WebSocketSession>();

	 private String userName="";
	
	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		userName = session.getAttributes().get("BROADCUST_USERNAME")+"";
		if(userSocketSessionMap.get(userName) ==null ){
			userSocketSessionMap.put(userName, session);
		}
	}
	
	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
		
		   Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap
	                .entrySet().iterator();
		   
		   while(it.hasNext()){
			   Entry<String, WebSocketSession> entry = it.next();
			   if(entry.getValue().getId().equals(session.getId())){
				   userSocketSessionMap.remove(entry.getKey());
				   log.debug("socket session had removed username :"+entry.getKey());
				   break;
			   }
		   }
	}
		/**
		 * 处理消息
		 */
	@Override
	public void handleMessage(WebSocketSession session, WebSocketMessage<?> webSocketMessage) throws Exception {
	     if(webSocketMessage.getPayloadLength()==0)return;
         Message msg=new Gson().fromJson(webSocketMessage.getPayload().toString(),Message.class);
         msg.setDate(new Date());
         sendMessageToUser(msg.getTo(), 
        		 new TextMessage(
        				 new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss")
        				 .create()
        				 .toJson(msg)));
	}

	@Override
	public void handleTransportError(WebSocketSession session, Throwable e) throws Exception {
		if(session.isOpen()){
			session.close();
		}
		   Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap
	                .entrySet().iterator();
		   while(it.hasNext()){
			   Entry<String, WebSocketSession> entry = it.next();
			   if(entry.getValue().getId().equals(session.getId())){
				   userSocketSessionMap.remove(entry.getKey());
				   log.debug("socket session had removed username :"+entry.getKey());
				   break;
			   }
		   }
	}

	@Override
	public boolean supportsPartialMessages() {
		return false;
	}

    public void sendMessageToUsers(TextMessage message) {
        for (WebSocketSession user : users) {
            try {
                if (user.isOpen()) {
                    user.sendMessage(message);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 发送消息给指定用户
     * @param userName
     * @param message
     * @throws IOException
     */
	  public void sendMessageToUser(String userName, TextMessage message) throws IOException {
		  WebSocketSession session = userSocketSessionMap.get(userName);
		  if(session != null && session.isOpen()){
			  session.sendMessage(message);
		  }
		  
	  }
	  
	  /**
	   * 群发消息
	   * @param msg
	   */
	  public void sendMsg(final TextMessage message ){
		   Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap
	                .entrySet().iterator();
		   while(it.hasNext()){
			   Entry<String, WebSocketSession> entry = it.next();
			   final WebSocketSession session = entry.getValue();
			   if(session !=null && session.isOpen()){
				   new Thread(new Runnable() {
					
					@Override
					public void run() {
						try {
							session.sendMessage(message);
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}).start();
			   }
		   }
	  }
	  
 
}
